package com.ifinc.common.socket.netty.client;

import com.ifinc.common.socket.simple_netty_client.SimpleClientMessageFactory;
import com.ifinc.common.socket.simple_netty_client.SimpleClientMessageHandler;
import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFactory;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.net.InetSocketAddress;
import java.util.concurrent.Executors;

/**
 * Created by IntelliJ IDEA.
 * User: luotao
 * Date: 12-5-30
 * Time: 14:50
 */

public class NettyClient {
    public ChannelFactory factory = null;

    ClientMessageFactory clientMessageFactory;

    @Autowired
    public void setClientMessageFactory(ClientMessageFactory clientMessageFactory) {
        this.clientMessageFactory = clientMessageFactory;
        init();
    }

    ClientBootstrap bootstrap;


    public void init() {
        factory = new NioClientSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool(), 8);
        bootstrap = new ClientBootstrap(factory);
        bootstrap.setPipelineFactory(clientMessageFactory);
        bootstrap.setOption("tcpNoDelay", true);
        bootstrap.setOption("keepAlive", true);
    }



    private void closeChannel(Channel channel, ChannelFuture lastWriteFuture) {
        channel.getCloseFuture().awaitUninterruptibly();
        // Wait until all messages are flushed before closing the channel.
        if (lastWriteFuture != null) {
            lastWriteFuture.awaitUninterruptibly();
        }

        // Close the connection.  Make sure the close operation ends because
        // all I/O operations are asynchronous in Netty.
        channel.close().awaitUninterruptibly();
        channel.close();
        // Shut down all thread pools to exit.

    }

    public void closeFactory() {
        bootstrap.releaseExternalResources();

//        System.out.println("receive sucess");
        factory.releaseExternalResources();
    }

    private Channel openChannel() {
        ChannelFuture future = bootstrap.connect(new InetSocketAddress("127.0.0.1", 8080));
        Channel channel = future.awaitUninterruptibly().getChannel();
        if (!future.isSuccess()) {
            future.getCause().printStackTrace();
            bootstrap.releaseExternalResources();
        }
        return channel;
    }



    public void sendData(){
        Channel channel = openChannel();
        ChannelBuffer buf = ChannelBuffers.buffer(1000);//(2)
        buf.writeBytes("hello".getBytes());
        buf.writeBytes("world".getBytes());
        ChannelFuture lastWriteFuture = channel.write(buf);
//        closeChannel(channel,lastWriteFuture);
//        closeFactory();
    }

    public static void main(String[] args) throws Exception {
        ClientMessageHandler simpleClientMessageHandler = new ClientMessageHandler();
        ClientMessageFactory simpleClientMessageFactory = new ClientMessageFactory();
        NettyClient simpleClientService = new NettyClient();

        simpleClientMessageFactory.setClientMessageHandler(simpleClientMessageHandler);
        simpleClientService.setClientMessageFactory(simpleClientMessageFactory);
        simpleClientService.sendData();
    }
}
